﻿/*
 *  Author: Louis A. Leskoviansky
 *  Company: Artemis Solutions Group (http://www.artemis-solutions.com)
 */


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;

namespace AjaxControlFramework
{
    public class InternalScriptManager
    {
        //------// Properties \\--------------------------------------------\\
        private Dictionary<string, ScriptReference> _registeredScripts = new Dictionary<string, ScriptReference>();
        public virtual Dictionary<string, ScriptReference> RegisteredScripts
        {
            get { return _registeredScripts; }
        }


        private Dictionary<string, ScriptReference> _renderedScripts = new Dictionary<string, ScriptReference>();
        public virtual Dictionary<string, ScriptReference> RenderedScripts
        {
            get { return _renderedScripts; }
        }


        private List<ScriptReference> _bodyScripts = new List<ScriptReference>();
        public virtual List<ScriptReference> BodyScripts
        {
            get { return _bodyScripts; }
        }


        private List<ScriptReference> _headScripts = new List<ScriptReference>();
        public virtual List<ScriptReference> HeadScripts
        {
            get { return _headScripts; }
        }


        public static InternalScriptManager Instance
        {
            get
            {
                if (HttpContext.Current.Items.Contains("AjaxControl.InternalScriptManager"))
                {
                    return (InternalScriptManager)HttpContext.Current.Items["AjaxControl.InternalScriptManager"];
                }
                else
                {
                    InternalScriptManager scriptManager = new InternalScriptManager();
                    HttpContext.Current.Items["AjaxControl.InternalScriptManager"] = scriptManager;

                    return scriptManager;
                }
            }
        }
        //------\\ Properties //--------------------------------------------//



        //------// Constructors \\------------------------------------------\\
        protected InternalScriptManager()
        {
            RegisterPreRenderEvent();
        }
        //------\\ Constructors //------------------------------------------//



        //------// Methods \\-----------------------------------------------\\
        public void RegisterScript(ScriptReference reference, ScriptRenderLocation renderLocation)
        {
            if (reference == null) { return; }

            if (!RegisteredScripts.ContainsKey(reference.Name))
            {
                RegisteredScripts.Add(reference.Name, reference);

                switch (renderLocation)
                {
                    case ScriptRenderLocation.Body:

                        BodyScripts.Add(reference);
                        break;

                    case ScriptRenderLocation.Head:

                        HeadScripts.Add(reference);
                        break;
                }
            }
        }


        public void RegisterEmbeddedScript(string name, string scriptName, string assembly, ScriptRenderLocation renderLocation)
        {
            RegisterScript(new EmbeddedScriptReference(scriptName, scriptName, assembly), renderLocation);
        }


        public void RegisterEmbeddedScript(string name, string scriptName, ScriptRenderLocation renderLocation)
        {
            RegisterEmbeddedScript(name, scriptName, null, renderLocation);
        }


        public void RegisterFileScript(string name, string sourcePath, ScriptRenderLocation renderLocation)
        {
            RegisterScript(new FileScriptReference(name, sourcePath), renderLocation);
        }


        public void RegisterInlineScript(string name, string sourceCode, ScriptRenderLocation renderLocation)
        {
            RegisterScript(new InlineScriptReference(name, sourceCode), renderLocation);
        }


        public void RegisterCompiledScript(string name, string sourcePath, ScriptRenderLocation renderLocation, ScriptType scriptType)
        {
            RegisterScript(new CompiledScriptReference(name, sourcePath, scriptType), renderLocation);
        }


        protected virtual void RegisterPreRenderEvent()
        {
            Page currentPage = HttpContext.Current.CurrentHandler as Page;

            if (currentPage != null)
            {
                HtmlControl body = null;

                // Attach to the <body>.
                //List<HtmlControl> controls = AjaxControlUtils.FindChildControlsByTagName((Control)currentPage.Master ?? currentPage, "body");

                List<HtmlControl> controls = AjaxControlUtils.FindChildControlsByTagName(AjaxControlUtils.FindTopMostParent(currentPage), "body");

                if (controls != null && controls.Count > 0)
                {
                    body = controls[0];
                }

                if (body != null)
                {
                    body.PreRender += new EventHandler(delegate(object source, EventArgs args)
                    {
                        RenderingHelper.RenderScriptBlocksAfterControl(BodyScripts, body);
                    });
                }


                // Attach to the <head>.
                if (currentPage.Header != null)
                {
                    currentPage.Header.PreRender += new EventHandler(delegate(object source, EventArgs args)
                    {
                        RenderingHelper.RenderScriptBlocksAfterControl(HeadScripts, currentPage.Header);
                    });
                }
            }
        }
        //------\\ Methods //-----------------------------------------------//
    }
}
